package ru.ifmo.croak.impl.storage.team1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.ifmo.croak.api.Message;
import ru.ifmo.croak.api.MessageListener;
import ru.ifmo.croak.api.MessageQuery;
import ru.ifmo.croak.api.QueryRequest;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Alex Vikharev
 *         22.05.11
 */
public class MessageQueryImpl implements MessageQuery {
    private final static Logger log = LoggerFactory.getLogger(MessageQueryImpl.class);

    private final QueryRequest queryRequest;
    private final Set<ListenerContainer> listeners;
    private final List<ListenerContainer> externalListeners;
    private final DatabaseBatchQuery databaseBatchQuery;

    private volatile boolean isClosed;

    public MessageQueryImpl(final QueryRequest queryRequest, final DatabaseBatchQuery databaseBatchQuery, final List<ListenerContainer> listeners) {
        this.queryRequest = queryRequest.clone();
        this.databaseBatchQuery = databaseBatchQuery;
        this.listeners = Collections.newSetFromMap(new ConcurrentHashMap<ListenerContainer, Boolean>());
        externalListeners = listeners;
        isClosed = false;
    }

    public QueryRequest getRequest() {
        return queryRequest;
    }

    public List<Message> getMessages() {
        return new BatchList(databaseBatchQuery);
    }

    public synchronized void close() {
        if (!isClosed) {
            isClosed = true;
            externalListeners.removeAll(listeners);
            listeners.clear();
        } else {
            throw new IllegalStateException("Attempt to close already closed MessageQuery");
        }
    }

    public synchronized void setMessageListener(final MessageListener listener) {
        if (!isClosed) {
            ListenerContainer container = new ListenerContainer(queryRequest, listener);
            listeners.add(container);
            externalListeners.add(container);
        } else {
            throw new IllegalStateException("Attempt to add listener to closed MessageQuery");
        }
    }
}
